//
//  LYDeviceInfo.swift
//  LYOnlineBanking
//
//  Created by 李永彬 on 2025/8/6.
//

import UIKit
import CoreTelephony
import SystemConfiguration.CaptiveNetwork
import NetworkExtension

struct LYDeviceInfo {
    static func getStorage() -> (total: Int64, free: Int64)? {
        guard let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last?.path else {
            return nil
        }
        
        do {
            let attributes = try FileManager.default.attributesOfFileSystem(forPath: path)
            let total = (attributes[.systemSize] as? NSNumber)?.int64Value ?? 0
            let free = (attributes[.systemFreeSize] as? NSNumber)?.int64Value ?? 0
            return (total, free)
        } catch {
            print("Error: \(error.localizedDescription)")
            return nil
        }
    }
    
    static func getSystemMemory() -> (free: UInt64, total: UInt64) {
        let totalMemory = ProcessInfo.processInfo.physicalMemory
        
        var hostSize = mach_msg_type_number_t(MemoryLayout<vm_statistics64_data_t>.size / MemoryLayout<integer_t>.size)
        var vmStat = vm_statistics64_data_t()
        let hostPort = mach_host_self()
        
        let result = withUnsafeMutablePointer(to: &vmStat) {
            $0.withMemoryRebound(to: integer_t.self, capacity: Int(hostSize)) {
                host_statistics64(hostPort, HOST_VM_INFO64, $0, &hostSize)
            }
        }
        
        guard result == KERN_SUCCESS else {
            print("获取内存信息失败: \(result)")
            return (0, totalMemory)
        }
        
        let pageSize = UInt64(vm_page_size)
        let free = UInt64(vmStat.free_count + vmStat.inactive_count) * pageSize
        return (free, totalMemory)
    }
    
    static func getBatteryInfo() -> (level: Float, isCharging: Bool) {
        let device = UIDevice.current
        
        // 获取电池电量（0.0 ~ 1.0，-1.0 表示未知）
        let batteryLevel = device.batteryLevel
        
        // 获取充电状态
        let isCharging: Bool
        switch device.batteryState {
        case .charging, .full:
            isCharging = true
        case .unplugged:
            isCharging = false
        case .unknown:
            isCharging = false // 默认未充电
        @unknown default:
            isCharging = false
        }
        
        return (batteryLevel, isCharging)
    }
    
    static var systemVersion: String {
        UIDevice.current.systemVersion
    }
    
    static var modelCode: String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        return machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
    }

    /// 根据原始设备型号获取设备名称和物理尺寸
    static func getDeviceInfo() -> (name: String, measure: Double)? {
        
        let screenSizeMap: [String: (name: String, measure: Double)] = [
            // iPhone 第一代
            "iPhone1,1": ("iPhone", 3.5),
            
            // iPhone 3G/3GS
            "iPhone1,2": ("iPhone 3G", 3.5),
            "iPhone2,1": ("iPhone 3GS", 3.5),
            
            // iPhone 4/4S
            "iPhone3,1": ("iPhone 4", 3.5),
            "iPhone3,2": ("iPhone 4", 3.5),
            "iPhone3,3": ("iPhone 4", 3.5),
            "iPhone4,1": ("iPhone 4S", 3.5),
            
            // iPhone 5/5C/5S
            "iPhone5,1": ("iPhone 5", 4.0),
            "iPhone5,2": ("iPhone 5", 4.0),
            "iPhone5,3": ("iPhone 5C", 4.0),
            "iPhone5,4": ("iPhone 5C", 4.0),
            "iPhone6,1": ("iPhone 5S", 4.0),
            "iPhone6,2": ("iPhone 5S", 4.0),
            
            // iPhone 6/6 Plus
            "iPhone7,1": ("iPhone 6 Plus", 5.5),
            "iPhone7,2": ("iPhone 6", 4.7),
            "iPhone8,1": ("iPhone 6S", 4.7),
            "iPhone8,2": ("iPhone 6S Plus", 5.5),
            "iPhone8,4": ("iPhone SE (1st)", 4.0),
            
            // iPhone 7/8
            "iPhone9,1": ("iPhone 7", 4.7),
            "iPhone9,2": ("iPhone 7 Plus", 5.5),
            "iPhone9,3": ("iPhone 7", 4.7),
            "iPhone9,4": ("iPhone 7 Plus", 5.5),
            "iPhone10,1": ("iPhone 8", 4.7),
            "iPhone10,2": ("iPhone 8 Plus", 5.5),
            "iPhone10,4": ("iPhone 8", 4.7),
            "iPhone10,5": ("iPhone 8 Plus", 5.5),
            
            // iPhone X/XS/XR/11
            "iPhone10,3": ("iPhone X", 5.8),
            "iPhone10,6": ("iPhone X", 5.8),
            "iPhone11,2": ("iPhone XS", 5.8),
            "iPhone11,4": ("iPhone XS Max", 6.5),
            "iPhone11,6": ("iPhone XS Max", 6.5),
            "iPhone11,8": ("iPhone XR", 6.1),
            "iPhone12,1": ("iPhone 11", 6.1),
            "iPhone12,3": ("iPhone 11 Pro", 5.8),
            "iPhone12,5": ("iPhone 11 Pro Max", 6.5),
            
            // iPhone 12 系列
            "iPhone13,1": ("iPhone 12 mini", 5.4),
            "iPhone13,2": ("iPhone 12", 6.1),
            "iPhone13,3": ("iPhone 12 Pro", 6.1),
            "iPhone13,4": ("iPhone 12 Pro Max", 6.7),
            
            // iPhone 13 系列
            "iPhone14,4": ("iPhone 13 mini", 5.4),
            "iPhone14,5": ("iPhone 13", 6.1),
            "iPhone14,2": ("iPhone 13 Pro", 6.1),
            "iPhone14,3": ("iPhone 13 Pro Max", 6.7),
            
            // iPhone 14 系列
            "iPhone14,6": ("iPhone SE (3rd)", 4.7),
            "iPhone14,7": ("iPhone 14", 6.1),
            "iPhone14,8": ("iPhone 14 Plus", 6.7),
            "iPhone15,2": ("iPhone 14 Pro", 6.1),
            "iPhone15,3": ("iPhone 14 Pro Max", 6.7),
            
            // iPhone 15 系列
            "iPhone15,4": ("iPhone 15", 6.1),
            "iPhone15,5": ("iPhone 15 Plus", 6.7),
            "iPhone16,1": ("iPhone 15 Pro", 6.1),
            "iPhone16,2": ("iPhone 15 Pro Max", 6.7)
        ]
        
        return screenSizeMap[self.modelCode]
    }
    
    /// 是否是模拟器（1: 是, 0: 否）
    static func isSimulator() -> Int {
        #if targetEnvironment(simulator)
        return 1
        #else
        return 0
        #endif
    }
    
    static func isJailbroken() -> Int {
        let jailbreakPaths = [
            "/Applications/Cydia.app",
            "/Library/MobileSubstrate/MobileSubstrate.dylib",
            "/bin/bash",
            "/usr/sbin/sshd",
            "/etc/apt",
            "/private/var/lib/apt/"
        ]
        
        for path in jailbreakPaths {
            if FileManager.default.fileExists(atPath: path) {
                return 1
            }
        }
   
        let stringToWrite = "Jailbreak Test"
        do {
            try stringToWrite.write(toFile: "/private/JailbreakTest.txt", atomically: true, encoding: .utf8)
            try FileManager.default.removeItem(atPath: "/private/JailbreakTest.txt")
            return 1
        } catch {
            return 0
        }
    }
    
    static var timezoneID: String {
        let seconds = TimeZone.current.secondsFromGMT()
        let hours = seconds / 3600
        return String(format: "GMT%+d", hours)
    }

    // MARK: - 是否使用代理（1: 是, 0: 否）
    static var isUsingProxy: Int {
        guard let proxySettings = CFNetworkCopySystemProxySettings()?.takeUnretainedValue() as? [String: Any],
              let httpProxy = proxySettings["HTTPProxy"] as? String,
              !httpProxy.isEmpty else {
            return 0
        }
        return 1
    }

    // MARK: - 是否使用 VPN（1: 是, 0: 否）
    static func isUsingVPN() -> Int {
        let vpnInterfaces = ["utun", "tun", "ppp", "ipsec"]
        var ifaddr: UnsafeMutablePointer<ifaddrs>?
        guard getifaddrs(&ifaddr) == 0 else { return 0 }
        
        var ptr = ifaddr
        while ptr != nil {
            defer { ptr = ptr?.pointee.ifa_next }
            let interface = ptr?.pointee
            let name = String(cString: interface!.ifa_name)
            if vpnInterfaces.contains(where: name.hasPrefix) {
                freeifaddrs(ifaddr)
                return 1
            }
        }
        freeifaddrs(ifaddr)
        return 0
    }

    // MARK: - 运营商名称（例如 "China Mobile"）
    static var carrierName: String {
        let networkInfo = CTTelephonyNetworkInfo()
        if #available(iOS 12.0, *) {
            guard let carrier = networkInfo.serviceSubscriberCellularProviders?.first?.value else {
                return "Unknown"
            }
            return carrier.carrierName ?? "Unknown"
        } else {
            guard let carrier = networkInfo.subscriberCellularProvider else {
                return "Unknown"
            }
            return carrier.carrierName ?? "Unknown"
        }
    }

    // MARK: - 设备语言（例如 "en"）
    static var deviceLanguage: String {
        return Locale.preferredLanguages.first?.components(separatedBy: "-").first ?? "en"
    }

    // MARK: - 网络类型（WIFI/4G/Bad Network/Unknown）
    static var networkType: String {
        guard let reachability = SCNetworkReachabilityCreateWithName(nil, "www.apple.com") else {
            return "Unknown Network"
        }
        
        var flags = SCNetworkReachabilityFlags()
        SCNetworkReachabilityGetFlags(reachability, &flags)
        
        if flags.contains(.isWWAN) {
            return "4G" // 移动网络
        } else if flags.contains(.reachable) {
            return "WIFI" // WiFi
        } else {
            return "Bad Network" // 无网络
        }
    }

    // MARK: - 是否是手机（1: 是, 0: 否）
    static var isPhone: Int {
        return UIDevice.current.userInterfaceIdiom == .phone ? 1 : 0
    }

    // MARK: - 获取 IP 地址（本地 WiFi IP）
    static var ipAddress: String {
        var address = "Unknown"
        var ifaddr: UnsafeMutablePointer<ifaddrs>?
        
        guard getifaddrs(&ifaddr) == 0 else { return address }
        var ptr = ifaddr
        
        while ptr != nil {
            defer { ptr = ptr?.pointee.ifa_next }
            
            let interface = ptr?.pointee
            let addrFamily = interface?.ifa_addr.pointee.sa_family
            
            // 只取 IPv4 地址
            if addrFamily == UInt8(AF_INET) {
                let name = String(cString: (interface?.ifa_name)!)
                if name == "en0" { // WiFi 接口
                    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                    getnameinfo(
                        interface?.ifa_addr,
                        socklen_t((interface?.ifa_addr.pointee.sa_len)!),
                        &hostname,
                        socklen_t(hostname.count),
                        nil,
                        socklen_t(0),
                        NI_NUMERICHOST
                    )
                    address = String(cString: hostname)
                }
            }
        }
        freeifaddrs(ifaddr)
        return address
    }

    // MARK: - 获取 WiFi 的 BSSID（MAC 地址）
    static var macAddress: String {
        guard let interfaces = CNCopySupportedInterfaces() as? [String] else {
            return "Unknown"
        }
        
        for interface in interfaces {
            guard let interfaceInfo = CNCopyCurrentNetworkInfo(interface as CFString) as? [String: Any],
                  let bssid = interfaceInfo["BSSID"] as? String else {
                continue
            }
            return bssid
        }
        return "Unknown"
    }
}
